import cgi
import logging
import os
import string
import urllib

from serverengine.lib import storage
from serverengine.lib import storageHelper #get the functions for file manipulation

from pylons import config, request, response, session, tmpl_context as c
from pylons.controllers.util import abort
try:
    from pylons.controllers.util import redirect_to
except:
    from pylons.controllers.util import redirect as redirect_to

from serverengine.lib.base import BaseController, render
from serverengine.lib import helpers

log = logging.getLogger(__name__)

class StoragesController(BaseController):
    """REST Controller styled on the Atom Publishing Protocol"""
    # To properly map this controller, ensure your config/routing.py
    # file has a resource setup:
    #     map.resource('storage', 'storages')

    def index(self,format='html'):
        """GET /storages: All items in the collection"""
        if not helpers.hasAuthorization():
            abort(401)
    
    def create(self):
        """POST /storages: Create a new item"""
        if not helpers.hasAuthorization():
            abort(401)
        
        directive="cp"
        if 'directive' in request.POST:
            directive=request.POST['directive']
        
        location=""
        if 'location' in request.POST:
            log.info("Requested location: %s " % request.POST['location'])
            location = helpers.unescape(request.POST['location'])
            log.info("Processed location: %s " % location)
        
        #mkdir--directive is mkdir
        if string.lower(directive)=="mkdir" and 'label' in request.POST:
            log.info("Making Directory")
            
            if len(request.POST['label'].lstrip()) == 0:
                abort(400)
                
            try:
                label = request.POST['label'].lstrip()
                filepath = os.path.join(storage.getUserPath(), session['user']['username'], location)
                log.info("Creating at %s/%s" % (filepath, label))
                storageHelper.createDirectory(filepath, label)
                return ""
            except:
                abort(403)

        #upload files--directive is cp 
        elif 'fileIO' in request.POST and string.lower(directive)=="cp":
            log.info("Uploading files")
            
            fileQueue = request.POST.getall('fileIO')
            filepath = os.path.join(storage.getUserPath(), session['user']['username'], location)
            log.info("Destination [%s]" % filepath)
            
            ret = []
            
            numberOfCompleteUploads = 0

            for fileIO in fileQueue:
                try:
                    fileIO.filename
                except:
                    continue

                #check if exceed file quota
                fileSize=len(fileIO.value)
                if (fileSize> int(storage.getUploadQuota()) ):
                    log.info("Size exceed quota %s" % fileSize )
                else:
                    filename = helpers.unescape(fileIO.filename).lstrip()
                    log.info("Writing [%s]" % filename)
                    fp = open(
                        os.path.join(
                            filepath,
                            filename
                        ),
                        'w'
                    )
                    fp.write(fileIO.value)
                    fp.close()
                    ret.append('Successfully uploaded: %s, size: %i' % \
                        (filename, fileSize))
                    numberOfCompleteUploads += 1
                #except:
                    #ret.append('Failed to upload a file')
            
            sizePath = os.path.join(storage.getUserPath(), request.POST['userID'])
            usedSize = str(storage.getDirSize(sizePath))
            quota = config['quotasize']
            
            if numberOfCompleteUploads > 0:
                ret = '<script>parent.actions.filesystem.uploadSucceeded();</script>' + '<br/>'.join(ret)
            else:
                ret = '<script>parent.actions.filesystem.uploadFailed();</script>' + '<br/>'.join(ret)
            return ret
        
        else:
            abort(403)

    def new(self, format='html'):
        """GET /storages/new: Form to create a new item"""
        abort(405)

    def update(self, id,format='xml'):
        """PUT /storages/id: Update an existing item"""
        # Forms posted to this method should contain a hidden field:
        #    <input type="hidden" name="_method" value="PUT" />
        # Or using helpers:
        #    h.form(url('storage', id=ID),
        #           method='put')
        # url('storage', id=ID)
        response.headers['Content-Type'] = 'text/xml; charset=utf-8'
        
        if not helpers.hasAuthorization() or session['user']['username']!=id:
            log.warning('%s made an unauthorized entry',request.environ['REMOTE_ADDR']) 
            abort(401)
            
        try:
            method = "move"
            if 'method' in request.params:
                method = request.params['method']
            log.debug("Update / %s" % method)
            if string.lower(method) == "move":
                log.debug(request.params)
                source = request.params['source']
                destination = request.params['destination']
                return storage.move(id,source,destination)
        except:
            abort(403)

    def delete(self, id, format='xml'):
        """DELETE /storages/id: Delete an existing item"""
        # Forms posted to this method should contain a hidden field:
        #    <input type="hidden" name="_method" value="DELETE" />
        # Or using helpers:
        #    h.form(url('storage', id=ID),
        #           method='delete')
        # url('storage', id=ID)
        response.headers['Content-Type'] = 'text/xml; charset=utf-8'
        if not helpers.hasAuthorization() or session['user']['username']!=id:
            log.warning('%s made an unauthorized entry',request.environ['REMOTE_ADDR']) 
            abort(401)
        log.debug(request.params)
        try:
            fileList=request.params['where']
            return storage.delete(id,fileList)
        except:
            abort(403)      

    def show(self, id, format='xml'):
        """GET /storages/id: Show a specific item"""
        # url('storage', id=ID)
        response.headers['Content-Type'] = 'text/xml; charset=utf-8'
        
        if not helpers.hasAuthorization() :
            abort(401)
        
        if session['user']['username'] != id:
            log.warning('%s (%s) Tried to create new user',session['user']['username'],request.environ['REMOTE_ADDR'])
            abort(401)
        
        location = ''
        
        try:
            location = request.params['location']
        except:
            location = ""
        
        log.debug("Requesting: " + location)
        log.debug("Home: " + storage.getUserPath(id))
        
        try:
            if storage.dirExist( storage.getUserPath(id) ):
                log.debug("Normal access");
                return storage.showFiles(id, location)
            else:
                log.debug("First-time access");
                newDirectoryPath = storage.getUserPath(id)
                storageHelper.createDirectory(newDirectoryPath, newDirectoryPath)
                return storage.showFiles(id, "")
        except:
            log.error("Access denied to [%s]" % location)
            abort(403)

    def edit(self, id, format='html'):
        """GET /storages/id/edit: Form to edit an existing item"""
        # url('edit_storage', id=ID)
